package com.snail.study.nio;

/**
 * 1.通道（Channel）：负责连接
 *      java.nio.channels.Channel接口
 *          |-- SelectableChannel
 *              |-- SocketChannel
 *              |-- ServerSocketChannel
 *              |-- DatagramChannel
 *
 *              |-- Pipe.SinkChannel
 *              |-- Pipe.SourceChannel
 *
 * 2.缓冲区（Buffer）：负责数据的存取
 *
 * 3.选择器（Selector）：是SelectableChannel的多路复用器，用于监控SelectableChannel的IO状况。
 */

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * 网络数据传输（阻塞式IO）
 * @author tim
 * @since 2021/3/30
 */
public class BlockingNioTest {

    @Test
    public void client(){
        try {
            //1.获取客户端通道
            SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9898));
            FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
            //2.分配指定大小的缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            //3.读取本地文件，并发送到服务端
            while ( inChannel.read(buffer) != -1){
                buffer.flip();
                socketChannel.write(buffer);
                buffer.clear();
            }
            //4.关闭通道
            socketChannel.close();
            inChannel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Test
    public void server(){
        //先执行server，再执行client
        try {
            //1.获取通道
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
            //2.绑定端口
            serverSocketChannel.bind(new InetSocketAddress(9898));

            //3.获取客户端的通道
            SocketChannel socketChannel = serverSocketChannel.accept();
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            //4.接受客户端数据，保存到本地
            while (socketChannel.read(buffer) != -1){
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
            //5.关闭通道
            outChannel.close();
            socketChannel.close();
            serverSocketChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
